//
//  NSObject+Observer.m
//  WebViewJavaScript
//
//  Created by DKHS on 2018/1/10.
//  Copyright © 2018年 CBL. All rights reserved.
//

#import "NSObject+Observer.h"
#import <objc/runtime.h>
#import "ObserverData.h"
#import "DKObserver.h"

@implementation NSObject (Observer)

+ (void)load {
    [self swizzleMethod];
}

+ (void)swizzleMethod {
    Method originalRemoveMethod = class_getInstanceMethod([self class], @selector(removeObserver:forKeyPath:));
    Method directingRemoveMethod = class_getInstanceMethod([self class], @selector(removeCurrentObserver:forKeyPath:));
    method_exchangeImplementations(originalRemoveMethod, directingRemoveMethod);
    
    Method originalAddMethod = class_getInstanceMethod([self class], @selector(addObserver:forKeyPath:options:context:));
    Method directingAddMethod = class_getInstanceMethod([self class], @selector(addCurrentObserver:forKeyPath:options:context:));
    method_exchangeImplementations(originalAddMethod, directingAddMethod);
}

- (void)removeCurrentObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath {
    NSMutableArray *observers = [DKObserver sharedObserver];
    ObserverData *userPathData = [self observerKeyPath:keyPath];
    if (userPathData) {
        [observers removeObject:userPathData];
        [self removeCurrentObserver:observer forKeyPath:keyPath];
    }
}

- (void)addCurrentObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context {
    if (![self observerKeyPath:keyPath]) {
        ObserverData *userPathData = [[ObserverData alloc] initWithObjc:observer keyPath:keyPath];
        [[DKObserver sharedObserver] addObject:userPathData];
        [self addCurrentObserver:observer forKeyPath:keyPath options:options context:context];
    }
}

- (ObserverData *)observerKeyPath:(NSString *)keyPath {
    for (ObserverData *data in [DKObserver sharedObserver]) {
        if ([data.objc isEqual:self] && [data.keyPath isEqualToString:keyPath]) {
            return data;
        }
    }
    return nil;
}

- (BOOL)observedKeyPath:(NSString *)keyPath {
    id info = self.observationInfo;
    NSArray *array = [info valueForKeyPath:@"_observances"];
    for (id objc in array) {
        id properties = [objc valueForKeyPath:@"_property"];
        NSString *key = [properties valueForKeyPath:@"_keyPath"];
        if ([key isEqualToString:keyPath]) {
            return YES;
        }
    }
    return NO;
}

@end
